package com.flute.framework.data.mysql;

import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

import com.flute.framework.FluteMonitor;
import com.flute.framework.StandardDate;
import com.flute.framework.data.IRawdataParser;
import com.flute.framework.data.constants.Constants;
import com.flute.framework.data.impl.RawDataFileProvider;
import com.flute.framework.monitor.EventLogger;
import com.flute.tools.data.DataException;
import com.flute.tools.data.DataIterator;
import com.flute.tools.data.DataRecord;
import com.flute.tools.data.IEditor;
import com.flute.tools.util.ExceptionUtil;
import com.flute.tools.util.exceptoin.DataParserException;

public class MysqlDataPreparer implements IMysqlDataPreparer {

	private String tableName;
	private RawDataFileProvider dataProvider;
	private String failedFolder;
	private String backupFolder;
	private IRawdataParser<DataRecord, File> parser;
	private IEditor editor;
	private IEditor historyEditor;

	public MysqlDataPreparer(IEditor historyEditor, IEditor editor,
			String tableName, String failedFolder) {
		this.tableName = tableName;
		this.failedFolder = failedFolder;
		this.editor = editor;
		this.historyEditor = historyEditor;
	}

	public String getBackupFolder() {
		return backupFolder;
	}

	public void setBackupFolder(String backupFolder) {
		this.backupFolder = backupFolder;
	}

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public String getFailedFolder() {
		return failedFolder;
	}

	public void setFailedFolder(String failedFolder) {
		this.failedFolder = failedFolder;
	}

	public IEditor getEditor() {
		return editor;
	}

	public void setEditor(IEditor editor) {
		this.editor = editor;
	}

	@Override
	public void prepare() throws DataParserException {
		List<File> list = dataProvider.getRawDatas();
		if (StringUtils.isEmpty(backupFolder)) {
			throw new DataParserException("backup folder path is invalid");
		}
		String dateString = new StandardDate(Calendar.getInstance().getTime())
				.toDateByPattern("yyyy-MM-dd");

		for (File file : list) {

			try {
				DataIterator<DataRecord> it = parser.parse(file);
				editor.begineTransaction();
				historyEditor.begineTransaction();
				while (it.hasNext()) {
					DataRecord dr = new DataRecord();
					try {
						dr = it.next();
						String normalDateString = new StandardDate(new Date())
								.toNormalDateString();
						dr.AddField(Constants.UPDATE_DATE, normalDateString);
						dr.AddField(Constants.CREATE_DATE, normalDateString);
						editor.addRecord(dr);
						historyEditor.addRecord(dr, Boolean.TRUE);
					} catch (DataException e) {
						EventLogger.error("Failed to process data '"
								+ dr.toString() + "' at file '"
								+ file.getName() + "'.\n"
								+ ExceptionUtil.getExceptionContent(e),
								FluteMonitor.getImporterKey());
					}
				}
				historyEditor.commit();
				editor.commit();
				EventLogger.info("Succeed to parse file '" + file.getName()
						+ "'.", FluteMonitor.getImporterKey());
			} catch (DataParserException e) {
				EventLogger.error("Failed to parse file '" + file.getName()
						+ "'.", FluteMonitor.getImporterKey());
				try {
					if (failedFolder == null) {
						throw new NullPointerException(
								"failed folder path not be null,please check the prepare deploy XML file");
					}
					FileUtils.moveFileToDirectory(file, new File(failedFolder),
							Boolean.TRUE);
				} catch (IOException e1) {
					throw new DataParserException("Failed to move file '"
							+ file.getName() + "' to failed folder '"
							+ failedFolder + "'.");
				}
			}
			
			try {
				FileUtils.moveFileToDirectory(file, new File(backupFolder
						+ File.separator + dateString), Boolean.TRUE);
			} catch (IOException e) {
				EventLogger.error("Backup " + file.getName() + " is failed",
						FluteMonitor.getImporterKey());
				if (file.exists() && !file.delete()) {
					EventLogger.error("Failed to delete file " + file.getName() + " is failed",
							FluteMonitor.getImporterKey());
				}
			}
		}
	}

	public RawDataFileProvider getDataProvider() {
		return dataProvider;
	}

	public void setDataProvider(RawDataFileProvider dataProvider) {
		this.dataProvider = dataProvider;
	}

	public IRawdataParser<DataRecord, File> getParser() {
		return parser;
	}

	public void setParser(IRawdataParser<DataRecord, File> parser) {
		this.parser = parser;
	}

	public IEditor getHistoryEditor() {
		return historyEditor;
	}

	public void setHistoryEditor(IEditor historyEditor) {
		this.historyEditor = historyEditor;
	}

}
